#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

pthread_mutex_t count_mutex     = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  condition_var   = PTHREAD_COND_INITIALIZER;

void *functionCount1();
void *functionCount2();
int  count = 0;

#define COUNT_DONE  10
#define COUNT_HALT1  3
#define COUNT_HALT2  6

main()
{
   pthread_t thread1, thread2;

   pthread_create(&thread1, NULL, &functionCount1, NULL);
   pthread_create(&thread2, NULL, &functionCount2, NULL);

   pthread_join(thread1, NULL);
   pthread_join(thread2, NULL);

   printf("Final count: %d\n",count);

   exit(0);
}

// Escreva os numeros 1-3 e 8-10 como permitido pela functionCount2()

void *functionCount1()
{
   for(;;)
   {
// Trava mutex e aguarde sinal para liberar mutex
      pthread_mutex_lock( &count_mutex );

 // Espera enquanto functionCount2() executa o count
 // mutex desbloqueado se a variavel condition_var em functionCount2() é sinalizada

// pthread_cond_wait - unlocks the mutex and waits for the condition variable cond to be signaled.
      pthread_cond_wait(&condition_var, &count_mutex);
      count++;
      printf("Counter value functionCount1: %d\n",count);

      pthread_mutex_unlock(&count_mutex);

      if(count >= COUNT_DONE) return(NULL);
    }
}

// Escreva numeros 4-7

void *functionCount2()
{
    for(;;)
    {
       pthread_mutex_lock(&count_mutex);

       if(count < COUNT_HALT1 || count > COUNT_HALT2)
       {

/* Condição da declaração "se" foi cumprida.
Sinal para liberar threads em espera, libertando o mutex
Nota: functionCount1() agora é permitido modificar "count".*/

//pthread_cond_signal - restarts one of the threads that are waiting on the condition variable cond.
          pthread_cond_signal(&condition_var);
       }
       else
       {
          count++;
          printf("Counter value functionCount2: %d\n",count);
       }

       pthread_mutex_unlock(&count_mutex);

       if(count >= COUNT_DONE) return(NULL);
    }

}
